using System;
using System.Text;
using System.Text.RegularExpressions;
using ScrewTurn.Wiki.PluginFramework;

namespace ScrewTurn.Wiki.PluginPack
{
    /// <summary>
    /// Implements a Formatter Provider that allows to write multi-language content in Wiki Pages.
    /// </summary>
    [Serializable]
    public class MultilanguageContentPlugin : IFormatterProvider
    {
        private const string divStyle =
            "padding: 2px; margin-bottom: 10px; font-size: 11px; background-color: #FFFFC4; border: solid 1px #DDDDDD;";

        private const string notLocalizedMessage =
            @"<div style=""" + divStyle +
            @""">The content of this Page is <b>not</b> available in your language, and it is displayed in the default language of the Wiki. To change the language settings, please go to the <a href=""Language.aspx"">Language Selection</a> page.</div>";

        private const string standardMessage =
            @"<div style=""" + divStyle +
            @""">The content of this Page is localized in your language. To change the language settings, please go to the <a href=""Language.aspx"">Language Selection</a> page.</div>";

        private readonly ComponentInformation info = new ComponentInformation("Multilanguage Content Plugin 1.2.1",
                                                                              "ScrewTurn Software",
                                                                              "http://www.screwturn.eu");

        private string config;

        private string defaultLanguage = "en-us";
        private bool displayWarning;
        private IHost host;

        #region IFormatterProvider Members

        public bool PerformPhase1
        {
            get { return false; }
        }

        public bool PerformPhase2
        {
            get { return false; }
        }

        public bool PerformPhase3
        {
            get { return true; }
        }

        public string Format(string raw, ContextInformation context, FormattingPhase phase)
        {
            string result = ExtractLocalizedContent(context.Language, raw); // Try to load localized content
            bool notLocalized = false;
            bool noLocalization = false;
            if (result == null)
            {
                result = ExtractLocalizedContent(defaultLanguage, raw); // Load content in the default language
                notLocalized = true;
                noLocalization = false;
            }
            if (result == null)
            {
                result = raw; // The Page is not localized, return all the content
                notLocalized = false;
                noLocalization = true;
            }
            if (displayWarning && !noLocalization && context.Page != null)
            {
                if (notLocalized) return notLocalizedMessage + result;
                else return standardMessage + result;
            }
            else return result;
        }

        public void Init(IHost host, string config)
        {
            this.host = host;
            this.config = config;
            defaultLanguage = host.GetSettingValue(SettingName.DefaultLanguage);
            displayWarning = config.ToLowerInvariant().Equals("display warning");
        }

        public void Shutdown()
        {
        }

        public ComponentInformation Information
        {
            get { return info; }
        }

        #endregion

        private string ExtractLocalizedContent(string language, string content)
        {
            string head = "\\<" + language + "\\>", tail = "\\<\\/" + language + "\\>";
            var regex = new Regex(head + "(.+?)" + tail, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            Match match = regex.Match(content);
            var sb = new StringBuilder();
            while (match.Success)
            {
                sb.Append(match.Groups[1].Value);
                match = regex.Match(content, match.Index + match.Length + 1);
            }
            if (sb.Length > 0) return sb.ToString();
            else return null;
        }
    }
}